import akshare as ak
import pandas as pd
import time
import winsound
from datetime import datetime, timedelta

# 配置参数
DEBUG = False
SYMBOLS_DICT = {
    "OI0": "菜油"
}

BEEP_FREQ = 2000  # 蜂鸣频率(Hz)
BEEP_DURATION = 2000  # 蜂鸣时长(ms)
TRADE_HOURS = [
    (datetime.strptime("09:30:01", "%H:%M:%S").time(),
     datetime.strptime("11:30:01", "%H:%M:%S").time()),
    (datetime.strptime("13:00:01", "%H:%M:%S").time(),
     datetime.strptime("15:00:01", "%H:%M:%S").time()),
    (datetime.strptime("21:00:01", "%H:%M:%S").time(),
     datetime.strptime("23:00:01", "%H:%M:%S").time())
]

NIGHT_TRADE_HOURS = [
    (datetime.strptime("21:00:01", "%H:%M:%S").time(),
     datetime.strptime("23:00:01", "%H:%M:%S").time())
]


def is_trading_time():
    if DEBUG:
        return True
    """验证当前是否处于交易时段"""
    now = datetime.now()
    current_time = now.time()
    # 排除周末
    if now.weekday() >= 5:
        return False
    # 时段验证
    for start, end in TRADE_HOURS:
        if start <= current_time <= end:
            return True
    return False


def is_night_trading_time():
    if DEBUG:
        return True
    """验证当前是否处于交易时段"""
    now = datetime.now()
    current_time = now.time()
    # 排除周末
    if now.weekday() >= 5:
        return False
    # 时段验证
    for start, end in NIGHT_TRADE_HOURS:
        if start <= current_time <= end:
            return True
    return False


def get_next_trigger():
    """计算下次触发时间（5分钟的第5秒）"""
    now = datetime.now()
    # 计算下一个5分钟间隔
    next_trigger = now.replace(second=1, microsecond=0) + timedelta(minutes=1)
    # 处理午间休市
    if datetime.strptime("11:30:00", "%H:%M:%S") < next_trigger < datetime.strptime("13:00:05", "%H:%M:%S"):
        next_trigger = next_trigger.replace(hour=13, minute=0, second=2)

    if datetime.strptime("15:00:00", "%H:%M:%S") < next_trigger < datetime.strptime("21:00:00", "%H:%M:%S"):
        next_trigger = next_trigger.replace(hour=21, minute=0, second=2)

    return next_trigger


def fetch_kline_data(symbol):
    """获取最近3根5分钟K线数据"""
    try:
        # main_df = ak.futures_display_main_sina()
        df = ak.futures_zh_minute_sina(symbol=symbol, period="1")
        # 时间，开盘价，收盘价，最高价，最低价，成交量，持仓量
        df = df[['datetime', 'open', 'close', 'high', 'low', 'volume', 'hold']]
        df['datetime'] = pd.to_datetime(df['datetime'])
        # 排序并获取最后三根
        return df.sort_values('datetime').tail(3)
    except Exception as e:
        print(f"[{datetime.now()}] 数据获取失败：{str(e)}")
        return None


def validate_pattern_up_9400(df):
    """验证三K线阶梯形态"""
    if df is None or len(df) < 3:
        return False

    return df['high'].iloc[2] > 9400


def main():
    print(f"[{datetime.now()}] 启动期货商品监控...")

    while True:
        if is_trading_time():
            next_time = get_next_trigger()
            sleep_sec = (next_time - datetime.now()).total_seconds()

            if sleep_sec > 0:
                if not DEBUG:
                    time.sleep(sleep_sec)

                # 夜盘去掉股指期货
                symbols = SYMBOLS_DICT.keys()

                for symbol in symbols:
                    # 获取并验证数据
                    klines = fetch_kline_data(symbol)
                    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    if validate_pattern_up_9400(klines):
                        print(f"[{current_time}] {SYMBOLS_DICT[symbol]} 突破9400 入场条件！")
                        print(klines[['datetime', 'high', 'low', 'open', 'close']])
                        winsound.Beep(BEEP_FREQ, BEEP_DURATION)
                    else:
                        if not DEBUG:
                            # print(f"[{datetime.now()}] 未达到检测条件...")
                            pass

        else:
            time.sleep(60)
        if DEBUG:
            return


if __name__ == "__main__":
    print("测试声音")
    winsound.Beep(BEEP_FREQ, BEEP_DURATION)
    main()
